App Inventor开发人员概述
Ellen Spertus(spertus@google.com )
JoséDominguez(josmasflores@gmail.com)
4.3 simple_components_permissions.json
本文档提供了App Inventor源代码的高级概述,包括App Inventor所依赖的工具包和库,App Inventor中的不同子项目以及构建过程和执行期间的信息流。
App Inventor 和App Inventor 2 之间存在差异,这些将在适当时突出显示。
MIT App Inventor是一个相当大的系统,分为多个项目,每个项目都依赖于不同的开源技术。在展示每个项目的内容之前(第3部分),我们介绍了其中使用的一些技术。
Google Web Toolkit(GWT) 允许程序员用Java编写客户端 - 服务器应用程序,而不必担心远程过程调用(RPC)的细节,除了为RPC提供显式回调(一个用于成功调用,一个用于失败)。GWT将客户端代码编译为JavaScript,在JavaScript中运行,并且RPC在服务器上作为Java代码运行,通过HTTP完成通信。建议读者 在深入研究运行的App Inventor部分或响应用户浏览器的请求之前了解GWT。
Google App Engine (GAE)是一个云计算平台,支持用Java(或Python)编写的程序在Google服务器上运行和维护数据。App Inventor的原始内部版本直接构建在专有的Google基础架构上,但对于开源版本,使用第三方Objectify 数据存储API 重写为使用GAE 。
GWT和GAE可以很好地协同工作,GWT服务器可以在GAE服务器上运行。这就是App Inventor的工作方式,如图1所示。
图1:App Inventor客户端和服务器是使用GWT创建的,GWT将前端代码转换为JavaScript,JavaScript在用户浏览器中与GWT客户端库一起运行。后端作为Google App Engine服务在GWT服务器库上运行,使用第三方Objectify API进行数据存储。
如果您之前从未编写过Android应用程序,并且您打算使用组件,那么Hello,World教程 是一个很好的入门方法。如果您认真编写组件,还应完成“ 管理活动生命周期” 部分。
Kawa 是Scheme的一个免费实现, 它编译为Java字节代码,可以通过工具dx 将其转换 为Dalvik字节码。我们使用Scheme作为用户程序的内部表示,部分运行时库 用Scheme编写。这些编译为字节代码,并通过buildserver与我们的组件库(用Java编写)和外部库(用Java和C / C ++编写)相链接。
在App Inventor 2中,块编辑器已集成到浏览器中,而不是 App Inventor附带的Java Web Start应用程序。Blockly 是一个由Googler Neil Fraser创建的开源库,它是用JavaScript编写的(使用SVG)。
App Inventor发行版由以下子目录组成,前七个子目录包含子项目的源代码:
其余两个子目录包含静态文件:
图2-A显示了每个项目代码的运行位置。它被简化为只显示项目的名称(例如,blocklyeditor)而不是特定的构建目标(例如,BlocklyCompile)。可以在每个项目的文档(尚未编写)和每个项目目录中的Ant build.xml文件中找到更多详细信息。另请注意,构建服务器可以部署在任何云服务中,因此可以使用从GAE服务器可访问的任何服务器(包括本地在开发计算机中)。
图2-A:系统的组件及其运行位置。
外部基础架构组件为黑色,部分App Inventor为红色。
图3显示了不同子项目之间的运行时通信。
App Inventor的经典版本中的目录结构略有变化。而不是blocklyeditor 项目,存在以下两个文件夹:
组件数字也有差异。App Inventor classic描述如下:
图2-B显示了每个项目代码的运行位置。它被简化为只显示项目的名称(例如,blockslib)而不是特定的构建目标(例如,OpenBlocks)。可以在每个项目的文档(尚未编写)和每个项目目录中的Ant build.xml文件中找到更多详细信息。另请注意,尽管图表将Amazon EC2描述为部署系统部分的潜在平台,但其使用并非强制性。可以使用从GAE服务器可访问的任何服务器(包括在开发机器中本地)。
图2-B:系统组件及其运行位置。
外部基础架构组件为黑色,部分App Inventor为红色。
系统的几个部分需要知道存在哪些组件及其特征。此信息是在构建时通过一组注释处理器生成的,这些注释处理器在组件 源代码上运行并生成构建其他App Inventor项目所需的文件。(此处,“项目”是指App Inventor代码库的各个部分,而不是用户创建的项目。)这些文件可以在子目录appinventor / build / components中找到。
此文件由GWT客户端(appengine 项目的一部分)中Designer内的编辑器使用。 以下是AccelerometerSensor的按键,含义和示例值。
键 | 含义 | 样本值 |
名称 | 组件的名称 | AccelerometerSensor |
版 | 每当组件的API发生更改时(例如通过添加新属性),数字会递增 | 1 |
categoryString | 它应该出现在调色板上的部分 | 传感器 |
helpString | 当用户单击组件名称右侧的帮助图标时显示的描述性HTML文本 | “<p>可以检测到震动并测量加速度的不可见组件......” |
showOnPalette | 是否在调色板上显示组件(当前对于除Form之外的所有组件都是true,这是自动创建的) | 真正 |
不可见 | 对于GUI元素为false,对于非GUI元素(例如传感器)为true | 真正 |
iconName | 组件图标的路径,相对于“appinventor / appengine / src / com / google / appinventor” | 图片/ accelerometersensor.png |
性能 | 包含每个属性的名称,类型和默认值的列表 | [{“name”:“Enabled”, |
在构建用户项目时,buildserver 使用此文件按字母顺序列出组件名称,每行一个。
此文件由构建服务器 用于生成应用程序所需的权限,其条目包含每个组件的名称和所需权限,例如:
{“name”:“Clock”,“permissions”:[]},
{“name”:“ContactPicker”,
“权限”:[“android.permission.INTERNET”,
“android.permission.READ_CONTACTS”]}
此文件包含blockseditor使用的块的规范(通过blockslib),包括静态库函数和包含其方法,属性和事件的组件。它的页眉和页脚来自组件 项目中src / com / google / appinventor / components / scripts / templates目录中的静态文件OUTPUT_HEADER.txt和OUTPUT_FOOTER.txt 。在撰写本文时,ya_lang_def超过14,000行。这是一个小摘录:
<! - TinyWebDB组件 - >
<BlockGenus name =“TinyWebDB”initlabel =“TinyWebDB”
label-unique =“yes”editable-label =“no”kind =“command”
is-starter =“yes”is-terminator =“yes”color =“gray”>
<描述>
<text>与Web服务通信以存储和检索信息的不可见组件。</ text>
</描述>
<LangSpecProperties>
<LangSpecProperty key =“ya-kind”value =“component”/>
<LangSpecProperty key =“component-version”value =“2”/>
<LangSpecProperty key =“ya-event-1”value =“TinyWebDB-GotValue”/>
<LangSpecProperty key =“ya-event-2”value =“TinyWebDB-ValueStored”/>
<LangSpecProperty key =“ya-event-3”value =“TinyWebDB-WebServiceError”/>
<LangSpecProperty key =“ya-prop-1”value =“ServiceURL / read-write-property / text /”/>
<LangSpecProperty key =“ya-method-1”value =“TinyWebDB-GetValue”/>
<LangSpecProperty key =“ya-type-method-1”value =“Type-TinyWebDB-GetValue”/>
<LangSpecProperty key =“ya-method-2”value =“TinyWebDB-StoreValue”/>
<LangSpecProperty key =“ya-type-method-2”value =“Type-TinyWebDB-StoreValue”/>
</ LangSpecProperties>
</ BlockGenus>
此文件由Ant目标ComponentDocumentation生成(它不显示为任何其他目标或任务的依赖项)包含HTML中的参考文档。从组件的源代码中的注释或注释中提取描述。这是一段摘录:
<h2 id =“TinyDB”> TinyDB </ h2>
<p>持续在手机上存储值的不可见组件。</ p>
<H3>属性</ H3>
没有
<H3>活动</ H3>
没有
<H3>方法</ H3>
<DL>
<dt> <code>任何GetValue(文本标签)</ code> </ dt>
<dd>检索存储在给定标记下的值。</ dd>
<dt> <code> StoreValue(文本标签,任何valueToStore)</ code> </ dt>
<dd>将给定值存储在给定标记下。存储
应用程序重新启动时,手机会一直显示在手机上。</ dd>
</ DL>
许多外部库包含在子目录“appinventor / lib”下的发行版中。按目录列出,是:
我们通常遵循这些风格指南:
一个例外是我们对组件属性,方法和事件名称使用upper-camel-case(例如,“MoveTo”)。
官方App Inventor源位于mit-cml / appinventor-sources.git中的GitHub上。主要分支是:
定期会有其他分支用于特定目的,通常是代表长期发展的分支,通常单独审查。目前有一个“api4”分支,我们正在进行更改以支持4(或更高)的minSdk。
我们在公共服务上发布了两种类型的版本。我们将更重要的版本称为“组件版本”。组件版本包括对组件的更改,以便App Inventor程序员需要更新其App Inventor Companion的版本,并且我们还需要更新构建服务器(人们)能够使用新的/修改过的组件。因为项目标有他们构建的组件的版本,所以一旦我们执行组件发布,我们就无法回去!值得注意的是,组件版本需要App Inventor程序员的工作,因为他们必须在他们的设备和/或他们的Android模拟器副本中更新AI2 Companion。由于需要的努力和测试,我们倾向于避免过多的组件发布过于紧密。一般来说,我们每个月都会进行一次组件发布。
相比之下,“非组件版本”是我们不更新组件的地方。例如,对App Inventor块图层或网站本身的其他功能的更改。如果出现问题,它们通常可以退出,并且它们确实需要App Inventor程序员的操作。
因为我们不希望经常进行组件发布,所以我们并不总是希望检查包含组件更改的主分支的更改。相反,我们有一个名为“ucr”的新分支,我们将合并通过审核的组件更改。当需要进行组件发布时,我们会在发布之前将ucr分支合并到主分支中。
应通过 GitHub工作流程对MIT App Inventor进行更改。通常我们不会使用GitHub来合并更改。相反,在查看更改之后,发布协调器会将您的提交压缩为单个提交,该提交将在主分支(非组件更改)或ucr分支(组件更改)上进行重新设置。通常作为这项工作的一部分,我们会将您的提交提交给我们的私人“Gerrit”评审服务器,该服务器将安排通过“Jenkins”持续集成系统自动运行我们的单元测试。通常,您无需了解此级别的详细信息。有时内部更改会绕过GitHub工作流程并直接在Gerrit上进行审核,尽管现在这种情况发生的频率较低。